#
# Copyright (C) [2024] Xingyun Integrated Circuit, Inc.
#
#   GreenCode was a private technology asset of Xingyun Integrated Circuit， Inc （Confidential）
#   Author :  Shawn.Tan
#   Date : 2025.10.28
#
#   History : Initial Version 2025.10.28
#
#

from gpgpu.exception_handlers.FastExceptionHandlersBase import (
    FastExceptionHandlersBaseGPGPU,
)


class FastEmptyHandlerGPGPU(FastExceptionHandlersBaseGPGPU):
    def processException(self):
        self.debug(
            "[FastEmptyHandlerGPGPU] process exception %s, privilege level: %s"
            % (self.mErrCode, self.mPrivLevel)
        )

        print(
            "[FastEmptyHandlerGPGPU] process exception %s, privilege level: %s"
            % (self.mErrCode, self.mPrivLevel)
        )


class FastSkipInstructionHandlerGPGPU(FastExceptionHandlersBaseGPGPU):
    def processException(self):
        self.debug(
            "[FastSkipInstructionHandlerGPGPU] process exception %s, "
            "privilege level: %s" % (self.mErrCode, self.mPrivLevel)
        )

        print(
            "[FastSkipInstructionHandlerGPGPU] process exception %s, "
            "privilege level: %s" % (self.mErrCode, self.mPrivLevel)
        )

        scratch_reg_index = self.mScratchRegisters[0]

        epc_name = (
            "mepc"
            if self.mPrivLevel == "M"
            else "sepc"
            if self.mPrivLevel == "S"
            else "unknown_pc_error"
        )

        self.mAssemblyHelper.genReadSystemRegister(scratch_reg_index, epc_name)
        self.mAssemblyHelper.genAddImmediate(scratch_reg_index, 4)
        self.mAssemblyHelper.genWriteSystemRegister(epc_name, scratch_reg_index)


class FastRecoveryAddressHandlerGPGPU(FastExceptionHandlersBaseGPGPU):
    def processException(self):
        self.debug(
            "[FastRecoveryAddressHandlerGPGPU] process exception %s, "
            "privilege level: %s" % (self.mErrCode, self.mPrivLevel)
        )

        scratch_reg_index = self.mScratchRegisters[0]
        recovery_reg_index = self.mScratchRegisters[1]

        # get the next address from the address table
        self.mAddrTable.getAddress(recovery_reg_index, scratch_reg_index)

        # update the appropriate epc with the recovery address
        epc_name = (
            "mepc"
            if self.mPrivLevel == "M"
            else "sepc"
            if self.mPrivLevel == "S"
            else "unknown_pc_error"
        )

        self.mAssemblyHelper.genWriteSystemRegister(epc_name, recovery_reg_index)
